package model
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator




class Crawler  {
	synchronized Collection errorQueue = new ArrayList()
	synchronized Collection waitingQueue = new ArrayList()
	synchronized Collection processedQueue = new ArrayList()

	protected boolean terminator= false

	protected CrawlerInterface inter


	Crawler(CrawlerInterface inter)
	{
		this.inter = inter
	}

	void addURL(URL url)
	{	if(terminator)
			return
		if ( getWaitingQueue().contains(url) )
			return
		if ( getErrorQueue().contains(url) )
			return
		if ( getProcessedQueue().contains(url) )
			return
		log("Adding to workload: " + url )
		getWaitingQueue().add(url)
	}

	void processURL(URL url)
	{	if(terminator)
			return

		try {
			log("Processing: " + url )
			CrawlerInfo.proccessingLink=url
			// get the URL's contents
			URLConnection connection = url.openConnection()
			if ( (connection.getContentType()!=null) && (
			!connection.getContentType().toLowerCase().startsWith("text/"))) {
				getWaitingQueue().remove(url)
				getProcessedQueue().add(url)
				log("Not processing because content type is: " +
						connection.getContentType() )
				return
			}

			// read the URL
			InputStream is = connection.getInputStream();
			Reader reader = new InputStreamReader(is);
			// parse the URL
			//HTMLEditorKit.Parser parse = new HTMLParse().getParser();
			//parse.parse(reader,new Parser(url),true);

			new ParserDelegator().parse(reader, new Parser(url), true)

		} catch ( IOException e ) {
			if(e.getMessage().contains("connect")){

				processURL(url)
				return
			}
			getWaitingQueue().remove(url)
			getErrorQueue().add(url)
			log("Error: " + url + " message "+e.getMessage())
			inter.urlError(url)
			return
		}
		if(terminator)
			return
		// mark URL as complete
		getWaitingQueue().remove(url)
		getProcessedQueue().add(url)
		log("Complete: " + url )
		Thread.sleep(200)
	}

	void start()
	{
		terminator = false;
		def thread = Thread.start{
			while ( !getWaitingQueue().isEmpty() && !terminator ) {
				ArrayList list = getWaitingQueue().toArray()

				for ( int i=0;(i<list.size())&&!terminator;i++ ){
					if(terminator)
						break

					processURL((URL)list[i])
					if(getWaitingQueue().size()==0)
						sleep(5000)

				}
			}
			if(!terminator)
				inter.scanFinished()
			log("Done!" + getProcessedQueue().size())
		}
		
	}

	Collection getErrorQueue() {
		return errorQueue
	}

	Collection getWaitingQueue() {
		return waitingQueue
	}

	Collection getProcessedQueue() {
		return processedQueue
	}
	void terminate()
	{
		terminator = true
		log("Scan terminated by the user")
	}

	void clear()
	{
		getErrorQueue().clear()
		getWaitingQueue().clear()
		getProcessedQueue().clear()
	}


	class Parser extends HTMLEditorKit.ParserCallback {
		protected URL host;
		int count = 0
		public Parser(URL host)
		{
			this.host = host;
		}

		public void handleSimpleTag(HTML.Tag tag,
				MutableAttributeSet a,int pos)
		{	  String href = (String)a.getAttribute(HTML.Attribute.HREF)
			if (href==null)
				return
			if(tag==HTML.Tag.IMG){
				href = (String)a.getAttribute(HTML.Attribute.SRC)
				if(href.contains(' ')){
					href.replaceAll(' ',"%20")

				}
				if(href.contains(" ")){
					href.replaceAll(" ","%20")
				}
				System.out.println("*******************************************************")

			}

			int i = href.indexOf('#');
			if ( i!=-1 )
				href = href.substring(0,i)
			if ( href.toLowerCase().startsWith("mailto:") ) {
				inter.foundEMail(href)
				return
			}



			handleLink(host,href,count++);

		}

		void handleStartTag(HTML.Tag tag,
				MutableAttributeSet a,int pos)
		{
			handleSimpleTag(tag,a,pos)    // handle the same way

		}

		void handleLink(URL host,String str, int count)
		{
			Thread.start{
				try { Thread.sleep(count*10)
					URL url = new URL(host,str);
					if ( inter.urlFound(host,url) ){
						if(terminator)
							return
						super.addURL(url)
					}
				} catch ( MalformedURLException e ) {
					super.log("Found malformed URL: " + str )
				}
			}
		}

	}

	void log(String entry)
	{
		System.out.println( ""+(new Date()) + ":" + entry )
	}



}
